#include <vector>
#include <deque>
#include <list>
#include <iostream>

using std::cout;
using std::endl;
using std::vector;
using std::deque;
using std::list;
using std::ostream;

//在写模板时，如果容器定义了这些成员类型时，
//根本就不需要知道具体的容器，他们都有这些成员类型
template <class Container>
void display(const Container & c)
{//形参使用了const关键字，则迭代器也必须要是const的
    typename Container::const_iterator it = c.begin();
    while(it != c.end()) {
        cout << *it << " ";
        ++it;
    }
    cout << endl;
}

class Point
{
public:
    Point(int ix = 0, int iy =0)
    : _ix(ix)
    , _iy(iy)
    {
        cout << "Point(int=0,int=0)" << endl;
    }

    Point(const Point & rhs)
    : _ix(rhs._ix)
    , _iy(rhs._iy)
    {
        cout << "Point(const Point & rhs)" << endl;
    }

    Point(Point && rhs)
    : _ix(std::move(rhs._ix))
    , _iy(std::move(rhs._iy))
    {
        cout << "Point(Point&&)" << endl;
    }
    
    friend ostream & operator<<(ostream & os, const Point & rhs);

private:
    int _ix;
    int _iy;
};

ostream & operator<<(ostream & os, const Point & rhs)
{
    os << "(" << rhs._ix
       << "," << rhs._iy
       << ")";
    return os;
}

void test0()
{
    vector<Point> numbers {
        {1, 1},
        {3, 3},
        {5, 5},
        {7, 7}
    };
    cout << "numbers's size:" << numbers.size() << endl;
    cout << "numbers's capacity:" << numbers.capacity() << endl;
    display(numbers);

    //使用push_back时，
    //如果传递过来的是左值，会进行拷贝构造
    //如果传递过来的是右值，会进行移动构造
    numbers.push_back(Point(9, 9));
    display(numbers);
    //使用emplace_back会直接在vector中进行原地构造
    //相比push_back效率更高，减少了一次构造
    numbers.emplace_back(11, 11);
    display(numbers);
}

void test1()
{
    cout << "\n test1()" << endl;
    vector<Point> numbers {
        {1, 1},
        {3, 3},
        {5, 5},
        {7, 7}
    };
    cout << "numbers's size:" << numbers.size() << endl;
    cout << "numbers's capacity:" << numbers.capacity() << endl;
    display(numbers);

    //当size == capacity时，emplace_back也要进行扩容
    //该函数内部会进行判断
    numbers.emplace_back(9, 9);
    cout << "numbers's size:" << numbers.size() << endl;
    cout << "numbers's capacity:" << numbers.capacity() << endl;
    display(numbers);
    //使用emplace_back会直接在vector中进行原地构造
    //相比push_back效率更高，减少了一次构造
    numbers.emplace_back(11, 11);
    display(numbers);
}

void test2()
{
}

int main()
{
    test0();
    test1();

    return 0;
}

